package com.wkbb.basic.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.wkbb.basic.feign.DoorFeignService;
import com.wkbb.basic.feign.TcCloudFeignService;
import com.wkbb.basic.mapper.*;
import com.wkbb.basic.model.*;
import com.wkbb.basic.service.ClassInfoService;
import com.wkbb.basic.service.GradeService;
import com.wkbb.basic.service.OrganizationService;
import com.wkbb.basic.service.StudentService;
import com.wkbb.basic.service.UserOpenService;
import com.wkbb.basic.thread.*;
import com.wkbb.basic.utils.BusinessUtil;
import com.wkbb.basic.utils.RandomUtil;
import com.wkbb.basic.vo.ClassManageEditVo;
import com.wkbb.basic.vo.TeacherCourseVo;
import com.wkbb.common.base.BaseServiceImpl;
import com.wkbb.common.business.BasicBusiness;
import com.wkbb.common.constants.ErrorCode;
import com.wkbb.common.constants.RedisKeyConstant;
import com.wkbb.common.dto.ResultDTO;
import com.wkbb.common.dto.basic.*;
import com.wkbb.common.dto.im.GroupUserInfoDto;
import com.wkbb.common.dto.im.ImUserDto;
import com.wkbb.common.enums.*;
import com.wkbb.common.handler.JsonUtil;
import com.wkbb.common.redis.RedisTemplateUtil;
import com.wkbb.common.utils.GradeUtil;
import com.wkbb.common.utils.StringUtil;
import com.wkbb.common.utils.ThreadPoolUtil;
import io.swagger.models.auth.In;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author Lilin
 */
@Service
@Slf4j
public class ClassInfoServiceImpl extends BaseServiceImpl<ClassInfo> implements ClassInfoService {

    @Autowired
    private EmployeeMapper employeeMapper;
    @Autowired
    private FamilyMapper familyMapper;
    @Autowired
    private TeacherCourseMapper teacherCourseMapper;
    @Autowired
    private StudentMapper studentMapper;
    @Autowired
    private ClassInfoMapper classInfoMapper;
    @Autowired
    private GradeMapper gradeMapper;
    @Autowired
    private TcCloudFeignService tcCloudFeignService;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private UserOpenService userOpenService;
    @Autowired
    private RedisTemplateUtil redisTemplateUtil;
    @Autowired
    private OrganizationMapper organizationMapper;
    @Autowired
    private OrganizationService organizationService;
    @Autowired
    private DoorFeignService doorFeignService;
    @Autowired
    private StudentService studentService;
    @Autowired
    private GradeService gradeService;

    @Autowired
    public void setMapper(ClassInfoMapper mapper) {
        super.setMapper(mapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultDTO<Boolean> joinClassByStudentsBack(String studentIds, Long classId,int type) {
        try {
            //删除关联表
            int delCount = studentMapper.deleteClassStudents(studentIds,classId);
            //如果有删除记录则全部重新排序
            Integer no = 0;
            if (delCount > 0){
                List<Student> students = studentMapper.findClassStudents(classId);
                for (Student student:students) {
                    no++;
                    student.setStudentNo(String.valueOf(no));
                    studentMapper.updateClassStudent(student);
                }
            }
            if (type == 1){
                if (delCount == 0) no = studentMapper.getClassMaxStudentNo(classId);
                List<Student> list = new ArrayList<>();
                if (no == null) no = 0;
                String[] ids = studentIds.split(",");
                for (String id:ids){
                    no++;
                    Student student = new Student();
                    student.setUserId(Long.parseLong(id));
                    student.setClassId(classId);
                    student.setStudentNo(String.valueOf(no));
                    list.add(student);
                }
//                log.info("--------------insertClassStudentBatch:{}", JsonUtil.stringify(list));
                studentMapper.insertClassStudentBatch(list);
            }
            return new ResultDTO();
        }catch (Exception e) {
            e.printStackTrace();
            return new ResultDTO(ErrorCode.SYSTEM_EXCEPTION);
        }
    }

    @Override
    public Map<String, Object> getClassAndGradeCount(Map<String, Object> params) {
        return classInfoMapper.getClassAndGradeCount(params);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultDTO<Boolean> joinClassByStudents(String studentIds, Long classId,int type) {
        ClassInfo oriClassInfo = classInfoMapper.getByPrimaryKey(classId);
        if (null == oriClassInfo) {
            return new ResultDTO(ErrorCode.CLASS_NOT_EXISTS);
        }
        if (oriClassInfo.getClassType() == 1) {
            return new ResultDTO(ErrorCode.CLASS_NORMAL);
        }
        try {
            //删除关联表
            int delCount = studentMapper.deleteClassStudents(studentIds,classId);
            //如果有删除记录则全部重新排序
            Integer no = 0;
            if (delCount > 0){
                List<Student> students = studentMapper.findClassStudents(classId);
                for (Student student:students) {
                    no++;
                    student.setStudentNo(String.valueOf(no));
                    studentMapper.updateClassStudent(student);
                }
            }
            if (type == 1){
                if (delCount == 0) no = studentMapper.getClassMaxStudentNo(classId);
                List<Student> list = new ArrayList<>();
                if (no == null) no = 0;
                String[] ids = studentIds.split(",");
                for (String id:ids){
                    no++;
                    Student student = new Student();
                    student.setUserId(Long.parseLong(id));
                    student.setClassId(classId);
                    student.setStudentNo(String.valueOf(no));
                    list.add(student);
                }
//                log.info("--------------insertClassStudentBatch:{}", JsonUtil.stringify(list));
                studentMapper.insertClassStudentBatch(list);
            }
            return new ResultDTO();
        }catch (Exception e) {
            e.printStackTrace();
            return new ResultDTO(ErrorCode.SYSTEM_EXCEPTION);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultDTO delete(List<Long> classIds, String updateBy) {

        if (classIds.isEmpty()) {
            return new ResultDTO(ErrorCode.PARAM_MISSING);
        }

        try {
            for (Long classId : classIds) {
                if (classId == null || classId == 0) {
                    return new ResultDTO(ErrorCode.PARAM_MISSING);
                }

                ClassInfo oriClassInfo = classInfoMapper.getByPrimaryKey(classId);
                if (null == oriClassInfo) {
                    return new ResultDTO(ErrorCode.CLASS_NOT_EXISTS);
                }

                log.info("-----查询原班级信息:{} {}", oriClassInfo.getOrgId(),oriClassInfo.getClassName());
                Long orgId = oriClassInfo.getOrgId();
                String className = oriClassInfo.getClassName();

                log.info("--------------------------批量删除班级校验用户----------------------------");
                //先判断班级中是否关联了老师和学生,如果有则提示不能直接删除
                Map<String, Object> paramMap = new HashMap<>();
                paramMap.put("orgId", orgId);
                paramMap.put("classId", classId);

                //1.先判断学生
                List<Student> students = studentMapper.getListByMapParams(paramMap);
                if (CollectionUtils.isNotEmpty(students)) {
                    //提示该班级已经关联了学生,不能直接删除此班级
                    return new ResultDTO(ErrorCode.CONNECTED_WITH_STUDENTS);
                }

                //2.接着判断任课老师
//                List<TeacherCourse> teacherCourseList = teacherCourseMapper.getListByMapParams(paramMap);
//                if (CollectionUtils.isNotEmpty(teacherCourseList)) {
//                    //提示改班级已经关联了任课老师,不能直接删除此班级
//                    String conTeacherCourse = String.format(ErrorCode.CONNECTED_WITH_TEACHER_COURSE.getMessage(), className);
//                    ErrorCode.CONNECTED_WITH_TEACHER_COURSE.setMessage(conTeacherCourse);
//                    return new ResultDTO(ErrorCode.CONNECTED_WITH_TEACHER_COURSE);
//                }

                log.info("--------------------------批量删除班级通讯录开始----------------------------");
                //3.如果设置了班主任,班主任退群,不删除IM账号
                Long masterUserId = oriClassInfo.getMasterId();
                if (null != masterUserId) {
                    //删除班主任
                    try {
                        log.info("**********删除班主任,删除所有相关教职工以及任课班级家长的通讯录**********");
                        Map<String, Object> params = new HashMap<>();
                        params.put("userId", oriClassInfo.getMasterId());
                        params.put("orgId", oriClassInfo.getOrgId());

                        Integer type = null;
                        Employee employee = employeeMapper.getByMapParams(params);
                        if (null != employee) {
                            if (employee.getUserType().intValue() == UserTypeEnum.TEACHER.getValue()) {
                                type = AddressListEnum.TEACHER.getValue();
                            } else {
                                type = AddressListEnum.PRINCIPAL.getValue();
                            }
                            log.info("**********删除班主任,删除所有相关教职工以及任课班级家长的通讯录**********");
                            ThreadPoolUtil.addPoolTask(new BacisDeleteAddressBookKeyTask(oriClassInfo.getMasterId(), type, oriClassInfo.getOrgId(), userOpenService));
                        }
                    } catch (Exception e) {
                        log.error("**********删除班主任,删除所有相关教职工以及任课班级家长的通讯录异常**********",e);
                    }

                    try {
                       // userOpenService.operateGroupUser(ImOperGroupTypeEnum.OUT_GROUP.getValue(), orgId, classId, masterUserId, null, RoleTypeEnum.TEACHER.getValue(), UserTypeEnum.TEACHER.getValue(), false);
                    }catch (Exception e) {
                        log.error("**********退班级群异常**********",e);
                    }

                }

                log.info("--------------------------批量删除班级解散群开始----------------------------");

                //4.通过feign先判断此班级是否已经创建了班级群,有则解散IM班级群(群组解散之后将无法恢复，请谨慎调用该接口)
                /*try {
                    ResultDTO<GroupUserInfoDto> resultDto = tcCloudFeignService.getAutoGroupInfoByClassId(classId, orgId);
                    if (null == resultDto || !resultDto.isSuccess()) {
                        return new ResultDTO(resultDto.isSuccess(), resultDto.getErrorCode(), resultDto.getErrorMsg());
                    }

                    if (null != resultDto.getData()) {
                        //证明已经创建了班级群
                        GroupUserInfoDto groupUserInfoDto = resultDto.getData();
                        if (groupUserInfoDto.getGroupIdentify()) {
                            String imGroupId = groupUserInfoDto.getImGroupId();
                            log.info("---imGroupId---{}", imGroupId);
                            ResultDTO destroyResultDto = tcCloudFeignService.destroyGroup(imGroupId);
                            log.info("---解散群---{}", JSONObject.toJSONString(destroyResultDto));
                            //如果是自动创建的班级群
                            if (destroyResultDto.isSuccess()) {
                                //data转成json
                                JSONObject dataJson = JSONObject.parseObject(destroyResultDto.getData().toString());
                                if (dataJson.get("ActionStatus").equals("FAIL")) {
                                    log.error("*****删除{}班级{}解散群异常{} {}******", orgId, classId, dataJson.get("ErrorCode").toString(), dataJson.get("ErrorInfo").toString());
                                }
                            }
                        }
                    }
                }catch (Exception e) {
                    log.error("**********解散群异常**********",e);
                }
*/
                log.info("--------------------------批量删除班级并清缓存----------------------------");
                Map<String, Object> teacherParams = new HashMap<>(2);
                teacherParams.put("classId", classId);
                teacherCourseMapper.deleteCourses(teacherParams);

                //5.既没有任课老师,又没有学生的情况下,直接删除班级
//                ClassInfo classInfo = new ClassInfo();
//                classInfo.setId(classId);
//                classInfo.setStatus(false);
//                classInfo.setUpdateBy(updateBy);
//                classInfo.setOrgId(orgId);
//                update(classInfo);
                classInfoMapper.deleteByPrimaryKey(classId);

                //清班级redis
                String key = BasicBusiness.getClassRedisKey(classId);
                redisTemplateUtil.delete(key);
            }
            return new ResultDTO();
        } catch (Exception e) {
            e.printStackTrace();
            return new ResultDTO(ErrorCode.SYSTEM_EXCEPTION);
        }
    }

    @Override
    public ClassInfo getInfo(Long classId) throws Exception {
        ClassInfo classInfo = getByPrimaryKey(classId);
        if (classInfo != null && !classInfo.getStatus()) {
            classInfo = null;
        }
        return classInfo;
    }

    @Override
    public ClassInfo getByPrimaryKey(Long id) throws Exception {
        //先查缓存
        String key = BasicBusiness.getClassRedisKey(id);
        ClassInfo classInfo = null;
        try {
            classInfo = (ClassInfo) redisTemplateUtil.get(key);
        } catch (Exception e) {
            e.printStackTrace();
        }

        //若无缓存，到数据库查
        if (classInfo == null) {
            classInfo = super.getByPrimaryKey(id);
            try {
                //添加到缓存
                redisTemplateUtil.set(key, classInfo);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        return classInfo;
    }

    @Override
    public void addTeacherCourse(List<Long> masterId, ClassInfo classInfo, String courseName) {
    	for(int i=0;i<masterId.size();i++){
    		
    		 TeacherCourse course = new TeacherCourse();
    	        course.setClassId(classInfo.getId());
    	        course.setMasterId(masterId.get(i));
    	        course.setGradeId(classInfo.getGradeId());
    	        course.setOrgId(classInfo.getOrgId());
    	        course.setOrgName(classInfo.getOrgName());
    	        course.setCourseName(courseName);

    	        teacherCourseMapper.insert(course);

    	        try {
    	            log.info("**********新增任课老师,删除所有相关教职工以及任课班级家长的通讯录**********");
    	            userOpenService.deleteRedisAddressBookKey(masterId.get(i), UserTypeEnum.TEACHER.getValue(), classInfo.getOrgId());
    	            log.info("**********新增任课老师,删除所有相关教职工以及任课班级家长的通讯录**********");
    	        } catch (Exception e) {
    	            log.error("**********新增任课老师,删除所有相关教职工以及任课班级家长的通讯录异常**********");
    	        }
    		
    	}
       

    }

    @Override
    public void deleteTeacherCourse(Long courseId) {
        teacherCourseMapper.deleteByPrimaryKey(courseId);
    }


    @Override
    public ClassInfo getClassMasterIsTrue(Long userId) {
        HashMap<String, Object> params = new HashMap<>(1);
        params.put("masterId", userId);
        return mapper.getByMapParams(params);
    }

    @Override
    public ClassInfoDto getClassInfoByMasterId(Long orgId, Long userId) {
        HashMap<String, Object> params = new HashMap<>(1);
        params.put("orgId", orgId);
        params.put("masterId", userId);
        return classInfoMapper.getClassInfoByMasterId(params);
    }

    @Override
    public List<TeacherCourse> getTeacherCourse(Map<String, Object> params) {
        return teacherCourseMapper.getListByMapParams(params);
    }


    /**
     * @Param type:1老師,2家長
     * Param   flag:自動創群開關
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String getAutoGroupFeign(Integer type, Boolean flag, Long userId, String className, Long orgId, Long classId, Long studentId) {

        String result = null;
        try {
            log.info("***********封装IM账号信息******type-{}", type);
            //班主任的用户ID
            List<NickNameDto> nickNameList = null;
            Employee employee = null;
            GroupUserInfoDto groupUserInfoDto = new GroupUserInfoDto();

            if (null != userId) {
                User user = userMapper.getByPrimaryKey(userId);
                log.info("***********输出用户ID和查询的用户信息******userId-{},user-{}", userId, user);

                if(null != user) {
                    if (RoleTypeEnum.TEACHER.getValue() == type) {
                        Map<String, Object> params = new HashMap<String, Object>();
                        params.put("orgId", orgId);
                        params.put("mobile", user.getMobile());
                        employee = employeeMapper.getByMapParams(params);
                        nickNameList = getNickNameDto(type, userId, orgId, classId, employee.getUserType(), studentId);
                    }
                    ResultDTO<ImUserDto> imUser = getImUserDtoResultDTO(orgId, user, employee.getUserType(), (short) RoleTypeEnum.TEACHER.getValue());
                    if (null != imUser) {
                        groupUserInfoDto.setUserKey(imUser.getData().getImAccount());
                    }
                    groupUserInfoDto.setUserHeadUrl(user.getHeadImgUrl());
                    groupUserInfoDto.setRelationTypeName(nickNameList.get(0).getNickName());
                    groupUserInfoDto.setUserId(userId);
                    groupUserInfoDto.setUserType(employee.getUserType());
                    groupUserInfoDto.setRoleIdentify(ImRoleIdentifyEnum.IMGROUPOWNER.getValue());
                }
            }
            groupUserInfoDto.setOrgId(orgId);
            groupUserInfoDto.setClassId(classId);

            if (RoleTypeEnum.TEACHER.getValue() == type && flag) {
                groupUserInfoDto.setRoleType(Short.parseShort("" + RoleTypeEnum.TEACHER.getValue()));
                groupUserInfoDto.setName(className + "(群)");
                groupUserInfoDto.setGroupIdentify(true);
                log.info("***********调用自动创群服务******");
                ResultDTO<Object> stringResultDTO = tcCloudFeignService.saveAutoGroup(groupUserInfoDto);

                if (ResultDTO.checkSuccess(stringResultDTO) && stringResultDTO.getData() != null) {
                    return stringResultDTO.getData().toString();
                }
            }
        } catch (Exception e) {
            log.error("***********调用自动创群或新成员自动入群异常***********", e);
        }
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addClass(ClassInfo classInfo, List<TeacherCourseVo> teacherCourseList) throws Exception {
        String insert = this.insert(classInfo, teacherCourseList);

       // this.saveClassAutoInfo(classInfo, teacherCourseList, insert);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String insert(ClassInfo classInfo, List<TeacherCourseVo> teacherCourseList) throws Exception {
        insert(classInfo);

        //获取学校负责人,并且自动为群主,若没有则不设置群主
        //OrganizationDto org = organizationService.getInfo(classInfo.getOrgId());

        //新增班级后触发IM自动创群
        //String autoGroupFeign = getAutoGroupFeign(RoleTypeEnum.TEACHER.getValue(), true, org.getMasterId(),BusinessUtil.subClassName(classInfo.getClassName()), classInfo.getOrgId(), classInfo.getId(), null);

        //return autoGroupFeign;
        
        return null;
    }

    @Override
    public void saveClassAutoInfo(ClassInfo classInfo, List<TeacherCourseVo> teacherCourseList, String autoGroupFeign) throws Exception {
        if (null != autoGroupFeign) {
            log.info("----------当前自动创群的群ID---------ImGroupId-{}", autoGroupFeign);
            //拉去班主任入群--------异步处理
            saveAutoClassMasterId(classInfo.getOrgId(), classInfo.getId(), classInfo.getMasterId(), true, autoGroupFeign);

            //拉取所有非学校负责人的园长入群---------异步处理
            saveAutoGroupUserMaster(classInfo.getOrgId(), UserTypeEnum.MASTER.getValue().shortValue(), classInfo.getId(), null, null);

            if (teacherCourseList == null || teacherCourseList.isEmpty()) {
                return;
            }

            teacherCourseList.forEach(teacherCourse -> insertTeacherCourse(classInfo, teacherCourse));

            //拉取任课老师入群-------异步处理
            saveAutoGroupUserTeacherCourse(classInfo.getOrgId(), classInfo.getId(), teacherCourseList, true, autoGroupFeign);
        }
    }

    @Override
    public void insert(ClassInfo entity) throws Exception {
        super.insert(entity);

        //添加缓存
        String key = BasicBusiness.getClassRedisKey(entity.getId());
        try {
            redisTemplateUtil.set(key, entity);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void insertTeacherCourse(ClassInfo classInfo, TeacherCourseVo teacherCourse) {
        if (teacherCourse == null || teacherCourse.getMasterId() == null || teacherCourse.getMasterId() == 0) {
            return;
        }

        teacherCourse.setGradeId(classInfo.getGradeId());
        teacherCourse.setOrgId(classInfo.getOrgId());
        teacherCourse.setClassId(classInfo.getId());
        teacherCourseMapper.insert(teacherCourse);

        try {
            log.info("*******新增任课老师,删除相关通讯录缓存*******");
            ThreadPoolUtil.addPoolTask(new ImDeleteRedisAddressBookKeyTask(teacherCourse.getMasterId(), AddressListEnum.TEACHER.getValue(), classInfo.getOrgId(), userOpenService));
        } catch (Exception e) {
            log.info("*******新增任课老师,删除相关通讯录缓存异常*******");
        }

    }

    @Override
    public void update(ClassInfo classInfo) throws Exception {
        update(classInfo, false);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(ClassInfo classInfo, boolean isBack) throws Exception {
        if (isBack) {
            //判断是否更改了年级,如果更改了年级字段,需要同步更新family表,student表,teacher_course表中gradeId
            //先查询原始的年级ID
            Long classId = classInfo.getId();
            Long orgId = classInfo.getOrgId();
            Long newGradeId = classInfo.getGradeId();
            ClassInfo oriClassInfo = classInfoMapper.getByPrimaryKey(classId);
            if (null != oriClassInfo) {
                if (oriClassInfo.getInviteCode() == null){
                    classInfo.setInviteCode(RandomUtil.generateString(8));
                }
                if (oriClassInfo.getGradeId().longValue() != newGradeId.longValue()) {
                    //同步更新family表中的gradeId
                    Map<String, Object> paramMap = new HashMap();
                    paramMap.put("orgId", orgId);
                    paramMap.put("classId", classId);
                    paramMap.put("status", 1);
                    List<Family> familyList = familyMapper.getListByMapParams(paramMap);
                    if (CollectionUtils.isNotEmpty(familyList)) {
                        for (Family family : familyList) {
                            if (family.getGradeId().longValue() != newGradeId.longValue()) {
                                family.setGradeId(newGradeId);
                                familyMapper.update(family);
                            }
                        }
                    }
                    //同步更新student表中的gradeId
                    paramMap.put("newGradeId",newGradeId);
                    studentMapper.updateGrade(paramMap);
//                    List<Student> studentList = studentMapper.getListByMapParams(paramMap);
//                    if (CollectionUtils.isNotEmpty(studentList)) {
//                        for (Student student : studentList) {
//                            if (student.getGradeId().longValue() != newGradeId.longValue()) {
//                                student.setGradeId(newGradeId);
//                                studentMapper.update(student);
//                            }
//                        }
//                    }
                    //同步更新teacher_course表中的gradeId
                    teacherCourseMapper.updateGrade(paramMap);
//                    List<TeacherCourse> teacherCourseList = teacherCourseMapper.getListByMapParams(paramMap);
//                    if (CollectionUtils.isNotEmpty(teacherCourseList)) {
//                        for (TeacherCourse teacherCourse : teacherCourseList) {
//                            if (teacherCourse.getGradeId().longValue() != newGradeId.longValue()) {
//                                teacherCourse.setGradeId(newGradeId);
//                                teacherCourseMapper.update(teacherCourse);
//                            }
//                        }
//                    }
                }
            }
            classInfoMapper.updateBack(classInfo);
        } else {
            super.update(classInfo);
        }

        //同步班级信息到门禁服务
       // ThreadPoolUtil.addPoolTask(new SynClassTask(doorFeignService, classInfo.getOrgId(), classInfo.getId()));

        //更新缓存
        String key = BasicBusiness.getClassRedisKey(classInfo.getId());
        try {
            ClassInfo newClassInfo = super.getByPrimaryKey(classInfo.getId());
            if (newClassInfo.getStatus()) {
                redisTemplateUtil.set(key, newClassInfo);
            } else {
                redisTemplateUtil.delete(key);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(ClassInfo classInfo, List<TeacherCourseVo> teacherCourseList, boolean isBack) throws Exception {
        //替换班主任时,删除班主任相关通讯录缓存
        ClassInfo classInfoOld = classInfoMapper.getByPrimaryKey(classInfo.getId());

        //异步处理删除通讯录,优化请求超时
        ThreadPoolUtil.addPoolTask(new ImDeleteRedisAddressBookKeyTask(classInfoOld.getMasterId(), AddressListEnum.TEACHER.getValue(), classInfoOld.getOrgId(), userOpenService));

        //更新班级信息
        update(classInfo, isBack);

        //----------------------取消代课老师(包括新增,删除代课老师)----------------------
        log.info("---------------------------------开始取消代课老师(包括新增,删除代课老师)---------------------------------");
        //新增一个字段oriMasterId原班主任
        Long orgId = classInfo.getOrgId();
        Long classId = classInfo.getId();
        Long oriMasterId = classInfo.getOriMasterId();
        Long masterId = classInfo.getMasterId();
        log.info("---开始更换班主任,全部参数:orgId={},classId={},oriMasterId={},masterId={}", orgId, classId, oriMasterId, masterId);

        //循环比对出,新增代课老师List,删除代课老师List
        Map<String, Object> paramsMap = new HashMap<>(1);
        paramsMap.put("orgId", orgId);
        paramsMap.put("classId", classId);
        //查询出原来(更改之前的任课老师们),与最后的任课老师们做对比
        List<TeacherCourse> oriTeacherCourseList = teacherCourseMapper.getListByMapParams(paramsMap);
        List<TeacherCourseVo> oriTeacherCourseVoList = new ArrayList<>(oriTeacherCourseList.size());
        for (TeacherCourse teacherCourse : oriTeacherCourseList) {
            TeacherCourseVo teacherCourseVo = new TeacherCourseVo();
            BeanUtils.copyProperties(teacherCourse, teacherCourseVo);
            oriTeacherCourseVoList.add(teacherCourseVo);
        }
        List<TeacherCourseVo> insertTeacherCourse = getTeacherCourseList(oriTeacherCourseVoList, teacherCourseList);
        List<TeacherCourseVo> deleteTeacherCourse = getTeacherCourseList(teacherCourseList, oriTeacherCourseVoList);
        log.info("-------入群的任课老师,判断此老师在同一班级任课门数,处理之前:------{}", JSONObject.toJSONString(insertTeacherCourse));
        log.info("-------退群的任课老师,判断此老师在同一班级任课门数,处理之前:------{}", JSONObject.toJSONString(deleteTeacherCourse));
        //循环判断新增的任课老师的身份(去除掉作为班主任时的任课老师)
        getTeacherCourseVoList(insertTeacherCourse, masterId, false);
        //在这里剔除园长,园长不需要退群
        if (CollectionUtils.isNotEmpty(deleteTeacherCourse)) {
            Iterator iterator = deleteTeacherCourse.iterator();
            while (iterator.hasNext()) {
                TeacherCourseVo teacherCourseVo = (TeacherCourseVo) iterator.next();
                //查询userType
                Map<String, Object> paramMap = new HashMap();
                paramMap.put("orgId", orgId);
                paramMap.put("userId", teacherCourseVo.getMasterId());
                Employee employee = employeeMapper.getByMapParams(paramMap);
                if (null != employee) {
                    if (employee.getUserType().intValue() == UserTypeEnum.MASTER.getValue()) {
                        iterator.remove();
                    }
                }
            }
        }
        getTeacherCourseVoList(deleteTeacherCourse, masterId, true);
        log.info("-------入群的任课老师,判断此老师在同一班级任课门数,处理之后:------{}", JSONObject.toJSONString(insertTeacherCourse));
        log.info("-------退群的任课老师,判断此老师在同一班级任课门数,处理之后:------{}", JSONObject.toJSONString(deleteTeacherCourse));
        //拉取任课老师入群
        if (CollectionUtils.isNotEmpty(insertTeacherCourse)) {
            log.info("--任课老师入群---start---");
            saveAutoGroupUserTeacherCourse(orgId, classId, insertTeacherCourse, true, null);
            log.info("--任课老师入群---end---");
        }
        //让任课老师退群
        if (CollectionUtils.isNotEmpty(deleteTeacherCourse)) {
            log.info("--任课老师退群---start---");
            saveAutoGroupUserTeacherCourse(orgId, classId, deleteTeacherCourse, false, null);
            log.info("--任课老师退群---end---");
        }
        log.info("---------------------------------取消代课老师(包括新增,删除代课老师)结束---------------------------------");
        //----------------------取消代课老师(包括新增,删除代课老师)----------------------

        Map<String, Object> params = new HashMap<>(1);
        params.put("classId", classInfo.getId());
        teacherCourseMapper.deleteCourses(params);

        //对比班级名称,如果不一样.调用修改IM群名称方法
        if (!classInfoOld.getClassName().equals(classInfo.getClassName())) {
            //更换IM群名称
            ThreadPoolUtil.addPoolTask(new ImUpdateGroupInfoTask(classInfo.getId(), classInfo.getOrgId(), BusinessUtil.subClassName(classInfo.getClassName()) + "(群)", ImGroupTypeEnum.AUTOGROUP.getValue(), tcCloudFeignService));
        }

        if (!CollectionUtils.isEmpty(teacherCourseList)) {
            //新增任课教师
            teacherCourseList.forEach(teacherCourse -> insertTeacherCourse(classInfo, teacherCourse));
        }

        //--------------------------------------以下代码,IM相关开始------------------------------------------
        log.info("---------------------------------开始更换班主任---------------------------------");
        if (null != oriMasterId && null != masterId && !oriMasterId.equals(masterId)) {
            //判断原班主任是否是老师，并且未代课,IM退群
            log.info("---判断原班主任是否是老师，并且未代课,IM退群---start---");
            inOrOutGroup(orgId, classId, oriMasterId, ImOperGroupTypeEnum.OUT_GROUP.getValue());
            log.info("---判断原班主任是否是老师，并且未代课,IM退群---end---");
            //判断新班主任是否是老师，并且未代课,IM入群
            log.info("---判断新班主任是否是老师，并且未代课,IM入群---start---");
            inOrOutGroup(orgId, classId, masterId, ImOperGroupTypeEnum.IN_GROUP.getValue());
            log.info("---判断新班主任是否是老师，并且未代课,IM入群---end---");
        }
        log.info("---------------------------------更换班主任结束---------------------------------");
        //--------------------------------------IM相关结束------------------------------------------
    }

    /**
     * 获取任课老师交集或差集
     *
     * @return 合并后的集合
     */
    private List<TeacherCourseVo> getTeacherCourseList(List<TeacherCourseVo> list1, List<TeacherCourseVo> list2) {
        if (CollectionUtils.isEmpty(list1) && CollectionUtils.isEmpty(list2)) {
            return new ArrayList<>();
        }
        List<TeacherCourseVo> newList = new ArrayList<>();
        Map<Long, TeacherCourseVo> cashMap = new HashMap<>(list1.size());
        list1.forEach(e -> {
            cashMap.put(e.getMasterId(), e);
        });
        list2.forEach(ee -> {
            if (cashMap.get(ee.getMasterId()) == null) {
                newList.add(ee);
            }
        });
        return newList;
    }

    /**
     * 再次过滤入群和退群列表
     *
     * @param teacherCourseList
     * @param masterId          班主任ID
     * @param isOut             是否退群
     * @return
     */
    private List<TeacherCourseVo> getTeacherCourseVoList(List<TeacherCourseVo> teacherCourseList, Long masterId, Boolean isOut) {
        if (CollectionUtils.isNotEmpty(teacherCourseList)) {
            Iterator iterator = teacherCourseList.iterator();
            while (iterator.hasNext()) {

                TeacherCourseVo teacherCourseVo = (TeacherCourseVo) iterator.next();
                if (null != masterId) {
                    //判断此新加的任课老师是否担任班主任,他之前是此班的班主任,现在换了班主任也换了任课老师
                    if (masterId.longValue() == teacherCourseVo.getMasterId().longValue()) {
                        //排除掉此任课老师,因为他已经作为班主任进群啦
                        iterator.remove();
                        continue;
                    }
                }

                //判断要退群的这些任课老师,是否真的能退群,如果担任一门课程的老师,可以直接退群,任多门课是不需要退群的
                Map<String, Object> paramMap = new HashMap<>();
                paramMap.put("orgId", teacherCourseVo.getOrgId());
                paramMap.put("classId", teacherCourseVo.getClassId());
                paramMap.put("masterId", teacherCourseVo.getMasterId());
                List<TeacherCourse> courseList = teacherCourseMapper.getListByMapParams(paramMap);
                //如果是退群操作
                if (isOut) {
                    if (CollectionUtils.isNotEmpty(courseList) && courseList.size() > 1) {
                        iterator.remove();
                    }
                } else {
                    //如果是入群操作
                    //判断要入群的这些任课老师,是否真的能入群,如果之前担任一门或多门课,都不需要再次入群
                    if (CollectionUtils.isNotEmpty(courseList)) {
                        iterator.remove();
                    }
                }
            }
        }
        return teacherCourseList;
    }

    private void inOrOutGroup(Long orgId, Long classId, Long userId, Integer operationType) {
        log.info("---inOrOutGroup--入参:--orgId={},classId={},userId={},operationType={}----", orgId, classId, userId, operationType);
        Map<String, Object> paramsMap = new HashMap<>();
        paramsMap.put("orgId", orgId);
        paramsMap.put("userId", userId);
        Employee employee = employeeMapper.getByMapParams(paramsMap);
        log.info("------inOrOutGroup--先查询是否存在此老师---employee={},userType={}", JSONObject.toJSONString(employee));
        if (null != employee) {
            log.info("---inOrOutGroup--userType={}", employee.getUserType());
            if (employee.getUserType().shortValue() == UserTypeEnum.TEACHER.getValue()) {
                paramsMap.clear();
                paramsMap.put("orgId", orgId);
                paramsMap.put("classId", classId);
                paramsMap.put("masterId", userId);
                List<TeacherCourse> teacherCourses = teacherCourseMapper.getListByMapParams(paramsMap);
                log.info("---此老师是否已经在此班级任课--{}", JSONObject.toJSONString(teacherCourses));
                if (CollectionUtils.isEmpty(teacherCourses)) {
                    ResultDTO resultDTO = userOpenService.operateGroupUser(operationType, orgId, classId, userId, null, RoleTypeEnum.TEACHER.getValue(), UserTypeEnum.TEACHER.getValue(), false);
                    log.info("--inOrOutGroup--入群或退群最终结果:{}", JSONObject.toJSONString(resultDTO));
                }
            }
        }
    }

    //更换负责人时更换群主
    @Override
    public void makeOverGroup(Long newMasterId, Long newOrgId, Long oldMasterId) {
        GroupUserInfoDto groupUserInfoDto = new GroupUserInfoDto();
        //如果更换班主任,触发IM自动转让群主
        if (!oldMasterId.equals(newMasterId)) {
            log.info("**********更换班主任准备触发转让群主**********");
            User user = userMapper.getByPrimaryKey(newMasterId);

            User oldUser = userMapper.getByPrimaryKey(oldMasterId);
            if (null != user) {
                //设置更换班主任的属性
                groupUserInfoDto.setChangeUserId(newMasterId);
                groupUserInfoDto.setChangeUserKey(user.getUserCode());

                groupUserInfoDto.setOrgId(newOrgId);
                //获取被更换人名称,以及userType,RoleType
                HashMap<String, Object> params = new HashMap<>(2);
                params.put("userId", newMasterId);
                params.put("orgId", newOrgId);
                Employee employee = employeeMapper.getByMapParams(params);
                if (null != employee) {
                    groupUserInfoDto.setUserType(employee.getUserType());
                    groupUserInfoDto.setRoleType((short) RoleTypeEnum.TEACHER.getValue());
                    //设置没有更换的班主任属性
                    groupUserInfoDto.setUserId(oldMasterId);
                    groupUserInfoDto.setUserKey(oldUser.getUserCode());
                    groupUserInfoDto.setUserHeadUrl(user.getHeadImgUrl());
                    groupUserInfoDto.setChangeRoleType(UserTypeEnum.MASTER.getValue().shortValue());
                    groupUserInfoDto.setChangeUserType(employee.getUserType());
                    //班主任的用户ID
                    List<NickNameDto> nickNameList = getNickNameDto(RoleTypeEnum.TEACHER.getValue(), newMasterId, newOrgId, null, employee.getUserType(), null);
                    groupUserInfoDto.setRelationTypeName(nickNameList.get(0).getNickName());

                    tcCloudFeignService.updateGroupOwner(groupUserInfoDto);

                }

            }
        }
    }

    @Override
    public ClassManageEditVo getClassInfoWithCoursesById(Long classId) {
        return classInfoMapper.getClassInfoWithCoursesById(classId);
    }

    @Override
    public List<ClassInfo> getClassMasterListByOrgId(Long orgId) {
        return classInfoMapper.getClassMasterListByOrgId(orgId);
    }

    public List<NickNameDto> getNickNameDto(Integer type, Long userId, Long orgId, Long classId, Short userType, Long studentId) {
        List<NickNameDto> nickNameList = new ArrayList<>();
        NickNameDto nickNameDto = new NickNameDto();
        nickNameDto.setUserId(userId);
        nickNameDto.setOrgId(orgId);
        nickNameDto.setClassId(classId);
        if (RoleTypeEnum.TEACHER.getValue() == type) {
            nickNameDto.setRoleType(RoleTypeEnum.TEACHER.getValue());
            nickNameDto.setUserType(userType.intValue());
        } else if (RoleTypeEnum.FAMILY.getValue() == type) {
            nickNameDto.setRoleType(RoleTypeEnum.FAMILY.getValue());
            nickNameDto.setStudentId(studentId);
        }
        nickNameList.add(nickNameDto);
        nickNameList = userOpenService.getNickName(nickNameList);
        return nickNameList;
    }

    @Override
    public void deleteTeacherCourseByMasterId(Long userId) {
        Map<String, Object> params = new HashMap<>(1);
        params.put("masterId", userId);

        teacherCourseMapper.deleteCourses(params);
    }

    @Override
    public void updateMaster(User user, String updateBy) {
        ClassInfo classInfo = new ClassInfo();
        classInfo.setMasterId(user.getId());
        classInfo.setMasterPhone(user.getMobile());
        classInfo.setMasterName(user.getName());
        classInfo.setUpdateBy(updateBy);
        classInfoMapper.updateMaster(classInfo);
    }

    //1.先循环学校
    //2.再循环学校下的班级
    //3.给每个班级设置班主任
    //4.IM自动建群
    @Override
    @Transactional
    public boolean autoCreateChatGroup(Long orgId) {
        Map orgMap = new HashMap();
        orgMap.put("status", 1);
        orgMap.put("orgType", OrganizationTypeEnum.KINDERGARTEN.getValue());
        //查询一个学校或者查询全部学校
        if (null != orgId) {
            orgMap.put("id", orgId);
        }
        List<Organization> organizationList = organizationMapper.getListByMapParams(orgMap);
        log.info("------------全部学校------------:{}", JSONObject.toJSONString(organizationList));
        if (!CollectionUtils.isEmpty(organizationList)) {
            for (Organization organization : organizationList) {
                //找到班级
                Map classMap = new HashMap();
                classMap.put("orgId", organization.getId());
                List<ClassInfo> classInfoList = classInfoMapper.getListByMapParams(classMap);
                log.info("------------学校orgId:{}------------班级列表classInfoList:{}", organization.getId(), JSONObject.toJSONString(classInfoList));
                if (!CollectionUtils.isEmpty(classInfoList)) {
                    //为每个班级设置班主任
                    for (ClassInfo classInfo : classInfoList) {
                        //有班主任,则不需要重新设置,没有班主任,则需要设置第一个老师为班主任
                        Long masterId = classInfo.getMasterId();
                        if (null == masterId) {
                            Map employeeMap = new HashMap();
                            employeeMap.put("status", 1);
                            employeeMap.put("orgId", organization.getId());
                            employeeMap.put("classId", classInfo.getId());
                            List<EmployeeInfoDto> employeeInfoDtoList = employeeMapper.getEmployeeInfoListByClassId(employeeMap);
                            log.info("------------学校orgId:{}------------班级classId:{}------------老师列表employeeInfoDtoList:{}", organization.getId(), classInfo.getId(), JSONObject.toJSONString(employeeInfoDtoList));
                            if (!CollectionUtils.isEmpty(employeeInfoDtoList)) {
                                EmployeeInfoDto employeeInfoDto = employeeInfoDtoList.get(0);
                                if (null != employeeInfoDto) {
                                    log.info("-----默认第一个老师作为班主任来创建群-----:{}", JSONObject.toJSONString(employeeInfoDto));
                                    masterId = employeeInfoDto.getUserId();
                                    ClassInfo editClassInfo = new ClassInfo();
                                    editClassInfo.setId(classInfo.getId());
                                    editClassInfo.setMasterId(masterId);
                                    editClassInfo.setMasterName(employeeInfoDto.getName());
                                    editClassInfo.setMasterPhone(employeeInfoDto.getMobile());
                                    classInfoMapper.update(editClassInfo);
                                }
                            }
                        }
                        //自动建群
                        getAutoGroupFeign(RoleTypeEnum.TEACHER.getValue(), true, masterId, classInfo.getClassName(), classInfo.getOrgId(), classInfo.getId(), null);
                    }
                }
            }
        }
        return true;
    }

    @Override
    public List<ClassInfoDto> getNewClassListByOldIds(List<Long> oldClassIds) {
        return classInfoMapper.getNewClassListByOldIds(oldClassIds);
    }

    //封装老师自动入群
    @Override
    public void userIdSwictch(Long userId, Long orgId, Long classId, String imGroupId) {
        List<TeacherCourseVo> teacherCourseList = new ArrayList<>();
        TeacherCourseVo teacherCourseVo = new TeacherCourseVo();
        teacherCourseVo.setMasterId(userId);
        teacherCourseList.add(teacherCourseVo);

        saveAutoGroupUserTeacherCourse(orgId, classId, teacherCourseList, true, imGroupId);
    }

    @Override
    public void saveAutoGroupUserTeacherCourse(Long orgId, Long classId, List<TeacherCourseVo> teacherCourseList, Boolean flag, String imGroupId) {
        List<GroupUserInfoDto> groupUserInfoDtoList = new ArrayList<>();

        if (null != teacherCourseList && teacherCourseList.size() > 0) {

            //获取所有新增任课老师
            for (TeacherCourseVo teacherCourse : teacherCourseList) {
                groupUserInfoDtoList = autoTeacher(orgId, classId, flag, groupUserInfoDtoList, null, teacherCourse.getMasterId(), imGroupId);
            }

            imGroupUserManage(groupUserInfoDtoList);

        }

    }


    public List<GroupUserInfoDto> autoTeacher(Long orgId, Long classId, Boolean flag, List<GroupUserInfoDto> groupUserInfoDtoList, ResultDTO<GroupUserInfoDto> autoGroupInfoByClassId, Long userId, String imGroupId) {
        User user = userMapper.getByPrimaryKey(userId);

        try {

            OrganizationDto info = organizationService.getInfo(orgId);

            if (null != user) {
                Employee employee = getEmployee(orgId, user);

                if (null != employee) {
                    List<NickNameDto> nickNameList = getNickNameDtos(orgId, employee);

                    GroupUserInfoDto groupUserInfoDto = getGroupUserInfoDto(orgId, classId, autoGroupInfoByClassId, user, employee.getUserType(), nickNameList, ImRoleIdentifyEnum.IMMANAGE.getValue(), (short) RoleTypeEnum.TEACHER.getValue());

                    groupUserInfoDto.setFlag(flag);

                    groupUserInfoDto.setImGroupId(imGroupId);
                    //新增需要增加的群成员
                    groupUserInfoDtoList.add(groupUserInfoDto);

                }
            }
        } catch (Exception e) {
            log.error("---------------班主任入群封装异常----------------", e);
        }
        return groupUserInfoDtoList;
    }

    @Override
    public void saveAutoClassMasterId(Long orgId, Long classId, Long classMasterId, Boolean flag, String imGroupId) {
        List<GroupUserInfoDto> groupUserInfoDtoList = new ArrayList<>();

        if (null != classMasterId) {
            groupUserInfoDtoList = autoTeacher(orgId, classId, flag, groupUserInfoDtoList, null, classMasterId, imGroupId);
        }
        log.info("--------班主任自动入群开始--------");
        imGroupUserManage(groupUserInfoDtoList);
        log.info("--------班主任自动入群结束--------");
    }

    public void imGroupUserManage(List<GroupUserInfoDto> groupUserInfoDtoList) {
        if (null != groupUserInfoDtoList && groupUserInfoDtoList.size() > 0) {

            ImSaveGroupUserTask imSaveGroupUserTask = new ImSaveGroupUserTask(tcCloudFeignService, groupUserInfoDtoList);
            ThreadPoolUtil.addTask(imSaveGroupUserTask);
        }
    }

    /**
     * 封装List对象
     *
     * @param orgId
     * @param classId
     * @param userId
     * @param userType
     * @return
     */
    @Override
    public List<GroupUserInfoDto> getGroupUserInfoDtoList(Long orgId, Long classId, Long userId, Long studentId, Integer userType) {
        List<GroupUserInfoDto> groupUserInfoDtoList = new ArrayList<>();
        ResultDTO<GroupUserInfoDto> groupUserInfo = tcCloudFeignService.getAutoGroupInfoByClassId(classId, orgId);

        //获取当前班级是否有自动创建群
        if (ResultDTO.checkSuccess(groupUserInfo) && groupUserInfo.getData() != null && null != groupUserInfo.getData().getImGroupId()) {
            User user = userMapper.getByPrimaryKey(userId);
            if (null != user) {
                if (userType.intValue() == UserTypeEnum.FAMILY.getValue()) {
                    HashMap<String, Object> params = new HashMap<>(4);
                    params.put("orgId", orgId);
                    params.put("classId", classId);
                    params.put("userId", userId);
                    params.put("studentId", studentId);
                    Family family = familyMapper.getByMapParams(params);

                    if (null != family) {
                        List<NickNameDto> nickNameList = getNickNameDto(RoleTypeEnum.FAMILY.getValue(), userId, orgId, classId, null, studentId);
                        log.info("---getGroupUserInfoDtoList---获取家长昵称---{}", JSONObject.toJSONString(nickNameList));

                        //因为多个事务问题,导致新增学生家长时候获取不到昵称
                        //先查询学生姓名,再查询学生和家长关系。然后拼接
                        User studentUser = userMapper.getByPrimaryKey(studentId);

                        String familyNickName = null;
                        if (null != studentUser) {
                            familyNickName = studentUser.getName() + RelationTypeEnum.getDesc(family.getRelationType());

                            if (null != nickNameList && nickNameList.size() > 0) {
                                for (NickNameDto nickName : nickNameList) {
                                    nickName.setNickName(familyNickName);
                                }
                            }
                        }

                        GroupUserInfoDto groupUserInfoDto = getGroupUserInfoDto(orgId, classId, groupUserInfo, user, UserTypeEnum.FAMILY.getValue().shortValue(), nickNameList, ImRoleIdentifyEnum.IMMEMBER.getValue(), (short) RoleTypeEnum.FAMILY.getValue());
                        log.info("---getGroupUserInfoDtoList---获取家长群用户信息getGroupUserInfoDto={}", JSONObject.toJSONString(groupUserInfoDto));
                        //新增需要增加的群成员
                        groupUserInfoDtoList.add(groupUserInfoDto);
                    }
                } else if (userType.intValue() == UserTypeEnum.TEACHER.getValue()) {
                    HashMap<String, Object> params = new HashMap<>(4);
                    params.put("orgId", orgId);
                    params.put("userId", userId);
                    Employee employee = employeeMapper.getByMapParams(params);
                    if (null != employee) {
                        List<NickNameDto> nickNameList = getNickNameDto(RoleTypeEnum.TEACHER.getValue(), userId, orgId, classId, employee.getUserType(), null);
                        log.info("---getGroupUserInfoDtoList---获取老师昵称---{}", JSONObject.toJSONString(nickNameList));
                        GroupUserInfoDto groupUserInfoDto = getGroupUserInfoDto(orgId, classId, groupUserInfo, user, employee.getUserType(), nickNameList, ImRoleIdentifyEnum.IMMANAGE.getValue(), (short) RoleTypeEnum.TEACHER.getValue());
                        log.info("---getGroupUserInfoDtoList---获取老师群用户信息getGroupUserInfoDto={}", JSONObject.toJSONString(groupUserInfoDto));
                        groupUserInfoDtoList.add(groupUserInfoDto);
                    }
                }
            }
        }
        return groupUserInfoDtoList;
    }

    @Override
    public void saveAutoGroupUserFamily(List<FamilyInfoDto> familyInfoListByClassIdList) {
        List<GroupUserInfoDto> groupUserInfoDtoList = getFamilyGroupUserInfoDto(familyInfoListByClassIdList);
        if (CollectionUtils.isNotEmpty(groupUserInfoDtoList)) {
            log.info("----------本次同步群成员人数----------size:{}", groupUserInfoDtoList.size());
            //调用新增群成员方法
            tcCloudFeignService.saveGroupUser(groupUserInfoDtoList);
        }
    }

    @Override
    public List<GroupUserInfoDto> getRepairFamilyList(List<FamilyInfoDto> familyInfoListByClassIdList) {
        return getFamilyGroupUserInfoDto(familyInfoListByClassIdList);
    }

    public List<GroupUserInfoDto> getFamilyGroupUserInfoDto(List<FamilyInfoDto> familyInfoListByClassIdList) {
        ResultDTO<GroupUserInfoDto> autoGroupInfoByClassId = tcCloudFeignService.getAutoGroupInfoByClassId(familyInfoListByClassIdList.get(0).getClassId(), familyInfoListByClassIdList.get(0).getOrgId());

        List<GroupUserInfoDto> groupUserInfoDtoList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(familyInfoListByClassIdList)) {
            for (FamilyInfoDto familyInfoDto : familyInfoListByClassIdList) {

                log.info("\n打印查询IM班级信息返回结果......" + RedisKeyConstant.WKBB_BASIC + "orgId:" + familyInfoDto.getOrgId() + "classId" + familyInfoDto.getClassId() + "autoGroupInfoByClassId" + ":{}", autoGroupInfoByClassId);
                //获取当前班级是否有自动创建群
                if (ResultDTO.checkSuccess(autoGroupInfoByClassId) && autoGroupInfoByClassId.getData() != null && null != autoGroupInfoByClassId.getData().getImGroupId()) {
                    User user = userMapper.getByPrimaryKey(familyInfoDto.getUserId());
                    //if (null != user) {
                    HashMap<String, Object> params = new HashMap<>(2);
                    params.put("orgId", familyInfoDto.getOrgId());
                    params.put("classId", familyInfoDto.getClassId());
                    params.put("userId", familyInfoDto.getUserId());
                    params.put("studentId", familyInfoDto.getStudentUserId());
                    Family family = familyMapper.getByMapParams(params);

                    log.info("\n打印家长返回结果......" + RedisKeyConstant.WKBB_BASIC + "orgId:" + familyInfoDto.getOrgId() + "classId" + familyInfoDto.getClassId() + "family" + ":{}", family);

                    if (null != family) {
                        List<NickNameDto> nickNameList = getNickNameDto(RoleTypeEnum.FAMILY.getValue(), familyInfoDto.getUserId(), familyInfoDto.getOrgId(), familyInfoDto.getClassId(), null, familyInfoDto.getStudentUserId());

                        //因为多个事务问题,导致新增学生家长时候获取不到昵称
                        //先查询学生姓名,再查询学生和家长关系。然后拼接
                        User studentUser = userMapper.getByPrimaryKey(familyInfoDto.getStudentUserId());

                        String familyNickName = null;
                        if (null != studentUser) {

                            familyNickName = studentUser.getName() + RelationTypeEnum.getDesc(family.getRelationType());

                            if (null != nickNameList && nickNameList.size() > 0) {
                                for (NickNameDto nickName : nickNameList) {
                                    if (StringUtil.isEmptyIgnoreBlank(nickName.getNickName())) {
                                        nickName.setNickName(familyNickName);
                                    }
                                }
                            }
                        }
                        log.info("\n打印昵称姓名返回结果......" + RedisKeyConstant.WKBB_BASIC + "orgId:" + familyInfoDto.getOrgId() + "classId" + familyInfoDto.getClassId() + "nickNameList" + ":{}", nickNameList);

                        GroupUserInfoDto groupUserInfoDto = getGroupUserInfoDto(familyInfoDto.getOrgId(), familyInfoDto.getClassId(), autoGroupInfoByClassId, user, UserTypeEnum.FAMILY.getValue().shortValue(), nickNameList, ImRoleIdentifyEnum.IMMEMBER.getValue(), (short) RoleTypeEnum.FAMILY.getValue());
                        //新增需要增加的群成员
                        groupUserInfoDtoList.add(groupUserInfoDto);

                    }
                }
            }
        }
        return groupUserInfoDtoList;
    }


    public GroupUserInfoDto getGroupUserInfoDto(Long orgId, Long classId, ResultDTO<GroupUserInfoDto> autoGroupInfoByClassId, User user, Short userType, List<NickNameDto> nickNameList, Short roleIdentify, Short roleType) {
        GroupUserInfoDto groupUserInfoDto = new GroupUserInfoDto();

        if (null != classId) {
            groupUserInfoDto.setClassId(classId);
        }
        groupUserInfoDto.setOrgId(orgId);
        groupUserInfoDto.setRoleType(roleType);
        groupUserInfoDto.setUserType(userType);
        groupUserInfoDto.setRelationTypeName(nickNameList.get(0).getNickName());
        groupUserInfoDto.setUserHeadUrl(user.getHeadImgUrl());
        groupUserInfoDto.setRoleIdentify(roleIdentify);
        groupUserInfoDto.setUserId(user.getId());
        if (null != autoGroupInfoByClassId) {
            groupUserInfoDto.setImGroupId(autoGroupInfoByClassId.getData().getImGroupId());
        }
        return groupUserInfoDto;
    }

    public ResultDTO<ImUserDto> getImUserDtoResultDTO(Long orgId, User user, Short userType, Short roleType) {
        //查询当前用户IM账号
        ResultDTO<ImUserDto> imUser = tcCloudFeignService.getImUser(orgId, user.getId(), roleType, userType);
        if (ResultDTO.checkSuccess(imUser) && imUser.getData() != null && null != imUser.getData().getImAccount()) {
            return imUser;
        }
        return null;
    }

    @Override
    public void saveAutoGroupUserMaster(Long orgId, Short userType, Long classId, Employee newEmployee, User newUser) throws Exception {
        log.info("---------是否新增的园长对象----------newEmployee:{}", JSONObject.toJSONString(newEmployee));
        log.info("---------是否新增的园长对象----------newUser:{}", JSONObject.toJSONString(newUser));

        //获取所有园长并且去除学校负责人
        OrganizationDto info = organizationService.getInfo(orgId);

        if (null != info) {
            Map<String, Object> params = new HashMap<String, Object>();
            params.put("orgId", orgId);
            params.put("userType", userType);
            if (null != info.getMasterId()) {
                params.put("userId", info.getMasterId());
            }

            Boolean flag = true;

            log.info("----saveAutoGroupUserMaster--getEmployeeMaster--方法参数:{}", params);
            List<Employee> employeeList = employeeMapper.getEmployeeMaster(params);
            log.info("----saveAutoGroupUserMaster.查询到所有园长并且去除学校负责人employeeList={}", JSONObject.toJSONString(employeeList));
            List<GroupUserInfoDto> newGroupUserInfoDtoList = new ArrayList<>();

            if (null != employeeList && employeeList.size() > 0) {

                if (null != newEmployee) {

                    for (Employee employee : employeeList) {
                        if (employee.getUserId().equals(newEmployee.getUserId())) {
                            flag = false;
                        }
                    }

                    if (flag) {
                        newGroupUserInfoDtoList = insertGroupUserInfo(orgId, newEmployee, newUser, newGroupUserInfoDtoList);
                    }
                }
            } else {

                log.info("------新增的园长自动入群------", JSONObject.toJSONString(newUser));


                if (null != newEmployee) {

                    newGroupUserInfoDtoList = insertGroupUserInfo(orgId, newEmployee, newUser, newGroupUserInfoDtoList);
                }
            }

            if (null != employeeList && employeeList.size() > 0) {

                log.info("---------输出所有的园长对象----------employeeList:{}", JSONObject.toJSONString(employeeList));

                for (Employee employee : employeeList) {
                    User user = userMapper.getByPrimaryKey(employee.getUserId());

                    if (null != user) {
                        List<NickNameDto> nickNameList = getNickNameDtos(orgId, employee);
                        //封装好园长对象
                        newGroupUserInfoDtoList = getNewGroupUserInfoDtoList(orgId, newGroupUserInfoDtoList, employee, user, nickNameList);

                    }

                }
                try {
                    log.info("---------------开启所有园长入IM所有群----------------");
                    log.info("------所有准备入群的园长:{}", JSONObject.toJSONString(newGroupUserInfoDtoList));
                    log.info("------输出园长入群班级--------classId:{}", classId);

                    if (null != newGroupUserInfoDtoList && newGroupUserInfoDtoList.size() > 0) {

                        ImSaveAutoMasterTask imSaveAutoMasterTask = new ImSaveAutoMasterTask(tcCloudFeignService, newGroupUserInfoDtoList, orgId, classId);
                        ThreadPoolUtil.addTask(imSaveAutoMasterTask);
                    }
                } catch (Exception e) {
                    log.error("---------------开启所有园长入IM所有群异常----------------", e);
                }
            }
        }
    }

    public List<GroupUserInfoDto> getNewGroupUserInfoDtoList(Long orgId, List<GroupUserInfoDto> newGroupUserInfoDtoList, Employee employee, User user, List<NickNameDto> nickNameList) {
        GroupUserInfoDto groupUserInfoDto = getGroupUserInfoDto(orgId, null, null, user, employee.getUserType(), nickNameList, ImRoleIdentifyEnum.IMMANAGE.getValue(), (short) RoleTypeEnum.TEACHER.getValue());
        //调用IM封装接口
        newGroupUserInfoDtoList.add(groupUserInfoDto);

        return newGroupUserInfoDtoList;
    }

    public List<NickNameDto> getNickNameDtos(Long orgId, Employee employee) {

        List<NickNameDto> nickNameList = getNickNameDto(RoleTypeEnum.TEACHER.getValue(), employee.getUserId(), orgId, null, employee.getUserType(), null);

        return nickNameList;
    }

    @Override
    public void saveAutoGroupUserMasterOne(Long orgId, Short userType, Employee newEmployee, User newUser) throws Exception {
        log.info("---------是否新增的园长对象----------newEmployee:{}", JSONObject.toJSONString(newEmployee));
        log.info("---------是否新增的园长对象----------newUser:{}", JSONObject.toJSONString(newUser));

        //获取所有园长并且去除学校负责人
        OrganizationDto info = organizationService.getInfo(orgId);

        if (null != info) {
            Map<String, Object> params = new HashMap<String, Object>();
            params.put("orgId", orgId);
            params.put("userType", userType);
            if (null != info.getMasterId()) {
                params.put("userId", info.getMasterId());
            }

            log.info("----saveAutoGroupUserMaster--getEmployeeMaster--方法参数:{}", params);
            List<Employee> employeeList = new ArrayList<>();
            log.info("----saveAutoGroupUserMaster.查询到所有园长并且去除学校负责人employeeList={}", JSONObject.toJSONString(employeeList));
            List<GroupUserInfoDto> newGroupUserInfoDtoList = new ArrayList<>();

            log.info("------新增的园长自动入群------", JSONObject.toJSONString(newUser));

            if (null != newEmployee) {

                newGroupUserInfoDtoList = insertGroupUserInfo(orgId, newEmployee, newUser, newGroupUserInfoDtoList);

                log.info("---------输出所有的园长对象----------employeeList:{}", JSONObject.toJSONString(employeeList));

                try {
                    log.info("---------------开启所有园长入IM所有群----------------");
                    log.info("------所有准备入群的园长:{}", JSONObject.toJSONString(newGroupUserInfoDtoList));

                    if (null != newGroupUserInfoDtoList && newGroupUserInfoDtoList.size() > 0) {

                        ImSaveAutoMasterTask imSaveAutoMasterTask = new ImSaveAutoMasterTask(tcCloudFeignService, newGroupUserInfoDtoList, orgId, null);
                        ThreadPoolUtil.addTask(imSaveAutoMasterTask);
                    }
                } catch (Exception e) {
                    log.error("---------------开启所有园长入IM所有群异常----------------", e);
                }
            }

        }
    }

    public List<GroupUserInfoDto> insertGroupUserInfo(Long orgId, Employee newEmployee, User newUser, List<GroupUserInfoDto> newGroupUserInfoDtoList) {

        List<NickNameDto> nickNameList = getNickNameDtos(orgId, newEmployee);

        //封装好园长对象
        newGroupUserInfoDtoList = getNewGroupUserInfoDtoList(orgId, newGroupUserInfoDtoList, newEmployee, newUser, nickNameList);
        return newGroupUserInfoDtoList;
    }

    public Employee getEmployee(Long orgId, User user) {
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("orgId", orgId);
        params.put("mobile", user.getMobile());
        return employeeMapper.getByMapParams(params);
    }

    public Family getFamily(Long orgId, User user) {
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("orgId", orgId);
        params.put("mobile", user.getMobile());
        return familyMapper.getByMapParams(params);
    }

    @Override
    @Transactional
    public void deleteByOrgId(Long orgId) {
        classInfoMapper.deleteByOrgId(orgId);
    }

    @Override
    public void imTeacherCourse(Long masterId, ClassInfo classInfo, Long orgId, Boolean isDelete) {
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("orgId", orgId);
        paramMap.put("classId", classInfo.getId());
        List<TeacherCourse> oriTeacherCourseList = teacherCourseMapper.getListByMapParams(paramMap);

        List<TeacherCourseVo> oriTeacherCourseVoList = new ArrayList<>();

        if (isDelete) {
            //任课老师删除封装
            if (null != oriTeacherCourseList && oriTeacherCourseList.size() > 0) {
                for (TeacherCourse teacherCourse : oriTeacherCourseList) {
                    if (!teacherCourse.getMasterId().equals(masterId)) {
                        TeacherCourseVo teacherCourseVo = new TeacherCourseVo();
                        teacherCourseVo.setMasterId(teacherCourse.getMasterId());
                        teacherCourseVo.setClassId(classInfo.getId());
                        oriTeacherCourseVoList.add(teacherCourseVo);
                    }
                }
            }

        } else {
            //任课老师新增封装
            if (null != oriTeacherCourseList && oriTeacherCourseList.size() > 0) {

                for (TeacherCourse teacherCourse : oriTeacherCourseList) {
                    TeacherCourseVo teacherCourseVo = new TeacherCourseVo();
                    BeanUtils.copyProperties(teacherCourse, teacherCourseVo);
                    oriTeacherCourseVoList.add(teacherCourseVo);
                }

                TeacherCourseVo teacherCourseVo = new TeacherCourseVo();
                teacherCourseVo.setMasterId(masterId);
                teacherCourseVo.setClassId(classInfo.getId());
                oriTeacherCourseVoList.add(teacherCourseVo);

            } else {
                TeacherCourseVo teacherCourseVo = new TeacherCourseVo();
                teacherCourseVo.setMasterId(masterId);
                oriTeacherCourseVoList.add(teacherCourseVo);
            }
        }

        try {
            log.info("-----------数据迁移开始调用任课老师入群----------");
            //调用修改班级信息接口
            if (!isDelete) {

                if (null != oriTeacherCourseVoList && oriTeacherCourseVoList.size() > 0) {
                    update(classInfo, oriTeacherCourseVoList, true);
                }
            } else {
                update(classInfo, oriTeacherCourseVoList, true);
            }
        } catch (Exception e) {
            log.error("-----------数据迁移开始调用任课老师入群异常----------", e);
        }
    }

    @Override
    public List<Long> getClassIdList() {
        return classInfoMapper.getClassIdList(new HashMap<>());
    }

    @Override
    public void repairImClassGroupInfoALL(List<Long> classIds) {
        HashMap<String, Object> param = new HashMap<>();
        param.put("ids", classIds);
        List<ClassInfo> classInfoList = classInfoMapper.getClassInfoById(param);

        try {
            log.info("----------准备修复班级数据----------classInfoList:{}", classInfoList);
            userOpenService.repairImGroupInfoByClassId(classInfoList, true);
        } catch (Exception e) {
            log.error("----------修复班级数据异常-----------", e);
        }
    }

    @Override
    public List<ImRepairClassMasterDto> getMasterAndTeacherCourseNum() {
        return classInfoMapper.getMasterAndTeacherCourseNum();
    }

    @Override
    public List<Long> getMasterAndTeacherCourse(Long id) {
        HashMap<String, Long> hashMap = new HashMap<>();
        hashMap.put("id", id);
        return employeeMapper.getMasterAndTeacherCourse(hashMap);
    }

    @Override
    public void upClass(Long orgId, Long newGradeId, Long classId, String className, Long masterId, String operateUser) {
        //查询待升级的班级信息
        ClassInfo classInfo = classInfoMapper.getByPrimaryKey(classId);
        log.info("***upClass****newGradeId:{} orignGradeId:{}", newGradeId, classInfo.getGradeId());
        if (!newGradeId.equals(classInfo.getGradeId())) {
            Boolean flag = false;
            try {
                flag = this.upGradeForClass(orgId, newGradeId, classId, className, masterId, operateUser, classInfo);
            } catch (Exception e) {
                log.error("*****upClass error******", e);
            }

            log.info("*****upClass flag:{}******", flag);

            //同步更新其他数据(学生 课程 考勤等)
            if (flag) {
                ThreadPoolUtil.addPoolTask(new ChangeClassTask(ChangeClassOperateTypeEnum.CHANGE_CLASS_TO_UP_CLASS.getCode(), studentService, doorFeignService, orgId, newGradeId, classId, null, operateUser));

                //解绑班级视频
               // ThreadPoolUtil.addPoolTask(new CommunityChangeVideoTask(communityFeignService,orgId,classId));
            }
        }

    }

    public boolean upGradeForClass(Long orgId, Long newGradeId, Long classId, String className, Long masterId, String operateUser, ClassInfo classInfo) {
        try{
            log.info("----------开始升班----------classId:{}",classId);
            //修改班级信息
            User user = userMapper.getByPrimaryKey(masterId);
            if (null != user) {
                classInfo.setOriMasterId(classInfo.getMasterId());
                classInfo.setMasterId(masterId);
                classInfo.setMasterName(user.getName());
                classInfo.setMasterPhone(user.getMobile());
            }

            Grade grade = gradeMapper.getByPrimaryKey(newGradeId);

            classInfo.setGradeId(newGradeId);
            classInfo.setGradeName(grade.getGradeName());//修改班级关联的年级名称
            if (StringUtil.isNotEmpty(className)) {
                classInfo.setClassName(className);
            }

            //查询任课老师
            Map<String, Object> paramsMap = new HashMap<>(1);
            paramsMap.put("orgId", orgId);
            paramsMap.put("classId", classId);
            List<TeacherCourse> oriTeacherCourseList = teacherCourseMapper.getListByMapParams(paramsMap);

            List<TeacherCourseVo> teacherCourseVoList = new ArrayList<>();
            // 判端是否为空
            if (CollectionUtils.isNotEmpty(oriTeacherCourseList)) {
                // 进行拆解封装
                teacherCourseVoList = oriTeacherCourseList.stream().map(oriTeacherCourse -> {
                    TeacherCourseVo teacherCourseVo = new TeacherCourseVo();
                    oriTeacherCourse.setOrgId(orgId);
                    oriTeacherCourse.setGradeId(newGradeId);
                    oriTeacherCourse.setClassId(classId);
                    BeanUtils.copyProperties(oriTeacherCourse, teacherCourseVo);
                    return teacherCourseVo;
                }).collect(Collectors.toList());
            }
            update(classInfo, teacherCourseVoList,  true);
            log.info("----------升班完成----------classId:{}",classId);
        }catch (Exception e){
            log.error("---------升班异常----------",e);
        }
        return true;
    }


    @Override
    public ClassInfo getByMapParams(Long orgId,String className){
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("orgId", orgId);
        params.put("className", className);
        return classInfoMapper.getByMapParams(params);
    }

    @Override
    public List<ClassInfoDto>  getCpClassListByOrg(Map<String, Object> params){

        return classInfoMapper.getCpClassListByOrg(params);
    }

	@Override
	public ClassInfo getClassByInviteCode(String InviteCode) {
		Map<String, Object> params = new HashMap<String, Object>();
        params.put("InviteCode", InviteCode);
		return classInfoMapper.getByMapParams(params);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void upGradeClass(Long orgId, Long gradeId, Long classId, String operateUser) throws Exception {
		
		 Organization organization = organizationService.getByPrimaryKey(orgId);
		 
		 short gradeType =GradeUtil.getGradeType(organization.getOrgType());
		 
		 if(null !=organization ){
			 
			 Map<String,Object> params = new HashMap<>();
			 
			 params.put("gradeType", gradeType);
			 
			 List<Grade> grades= gradeService.getListByMapParams(params);
			 
			 params.put("orgId", orgId);
			 
			 List<ClassInfoDto> classes = getCpClassListByOrg(params);
			 
			 Map<String,Object> map = new HashMap<>();
			 
			 Map<String,Object> gmap = new HashMap<>();
			 
			 Iterator<Grade> iteratorGrade = grades.iterator();
			 
			 String[] nj ={"一","二","三","四","五","六","七","八","九","十","十一","十二"};
			 
			 
			 while(iteratorGrade.hasNext()){
				 
				 Grade grade = (Grade) iteratorGrade.next();
				 
				//小学
				 if(gradeType==2 && grade.getGradeName().contains(nj[5])){
					 gmap.put("orgId", orgId);
					 gmap.put("gradeId", grade.getId());
					 studentMapper.studentGraduate(gmap);
					 continue;
				 }
				 //初中 高中
				 if((gradeType==4 || gradeType==5) && grade.getGradeName().contains(nj[2])){
					 gmap.put("orgId", orgId);
					 gmap.put("gradeId", grade.getId());
					 studentMapper.studentGraduate(gmap);
					 continue;
				 }
				 //9年一贯
				 if(gradeType==9 && grade.getGradeName().contains(nj[8])){
					 gmap.put("orgId", orgId);
					 gmap.put("gradeId", grade.getId());
					 studentMapper.studentGraduate(gmap);
					 continue;
				 }
				 //12年一贯
				 if(gradeType==10 && grade.getGradeName().contains(nj[11])){
					 gmap.put("orgId", orgId);
					 gmap.put("gradeId", grade.getId());
					 studentMapper.studentGraduate(gmap);
					 continue;
				 }
				 
				 Grade newGrade = null;
				 
				 for(int j =0;j<nj.length;j++){
					 if(grade.getGradeName().contains(nj[j])){
						 newGrade =	nextGrade(nj[j+1],grades);
						 break;
					 }
						 
					 
				 }
				 
				     map.put("orgId", orgId);
					 map.put("gradeId", grade.getId());
					 map.put("newGradeId", newGrade.getId());
					 
					 for(ClassInfoDto classInfoDto:classes){
						
						 if(classInfoDto.getGradeId()==grade.getId()){
							 
							 map.put("classId", classInfoDto.getId());
							 map.put("masterId", classInfoDto.getMasterId());
							 map.put("masterName", classInfoDto.getMasterName());
							 map.put("newClassId", nextClass(classInfoDto.getClassName(),classInfoDto.getGradeName(),newGrade,classes));
							 studentMapper.upGradeClass(map); //升级学生
							 classInfoMapper.upTeacher(map); //升级老师
						 }
					 }
					 
				 }
				 
		 }
		 
		
	}

    public Grade nextGrade(String newGrade,List<Grade> grades){
    	 
    	 Iterator<Grade> it = grades.iterator();
    	 
    	while(it.hasNext()){
    		Grade grade = (Grade) it.next();
    		if(grade.getGradeName().contains(newGrade)){
    			return grade;
    			
    		}
    		
    	}
    	
    	return null;
     }
     
     
     public Long nextClass(String oldClass,String oldGrade,Grade newGrade,List<ClassInfoDto> classes){
    	 
    	 String newClass = newGrade.getGradeName().concat(oldClass.split(oldGrade)[1]);
    	 
    	 for(ClassInfoDto classInfoDto:classes){
    		 
    		 
    		 if(classInfoDto.getClassName().equalsIgnoreCase(newClass) && classInfoDto.getGradeId().equals(newGrade.getId())){
    			 return classInfoDto.getId();
    		 }
    	 }
    	 
    	 return null;
    	 
     }
     
     
   

}
